package com.ts.api.module.api.service.impl;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.date.DateUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.productflow.ProductApplyFlowSrcTypeEnum;
import com.ts.api.common.constant.productflow.ProductApplyFlowStatusEnum;
import com.ts.api.common.constant.protocol.UserProtocolEnum;
import com.ts.api.common.localcache.DistrictCache;
import com.ts.api.common.util.H5DomainUrlUtils;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.exp.RollBackException;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.plan.http.ApiPlanHttpHandler;
import com.ts.api.module.api.convert.platform.entity.RespPlatformMultiPhoneMaskDataExchange;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMaskDataExchange;
import com.ts.api.module.api.convert.platform.entity.RespPlatformPhoneMd5DataExchange;
import com.ts.api.module.api.convert.receive.entity.ApiReceiveApply;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.bo.ApiKeyAmountBO;
import com.ts.api.module.api.entity.bo.ApiParameterBO;
import com.ts.api.module.api.entity.bo.ApiUserRegisterBO;
import com.ts.api.module.api.service.ApiBizApplyService;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.api.service.ApiKeyAmountService;
import com.ts.api.module.api.service.ApiUserRegister;
import com.ts.api.module.channel.entity.bo.SelectedUserFormBO;
import com.ts.api.module.channel.entity.po.ChannelUserRegisterPO;
import com.ts.api.module.channel.entity.qo.ChannelUserQO;
import com.ts.api.module.channel.service.ChannelUserService;
import com.ts.api.module.common.entity.DistrictPO;
import com.ts.api.module.common.service.SmsService;
import com.ts.api.module.product.entity.bo.ProductAmountBO;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductAmountService;
import com.ts.api.module.product.service.ProductPlanService;
import com.ts.api.module.product.service.ProductPlanTypeService;
import com.ts.api.module.product.service.ProductService;
import com.ts.api.module.protocol.entity.po.ProductProtocolPO;
import com.ts.api.module.protocol.entity.po.UserProtocolPO;
import com.ts.api.module.protocol.entity.qo.ProductProtocolQO;
import com.ts.api.module.protocol.service.ProductProtocolService;
import com.ts.api.module.protocol.service.UserProtocolService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
public class ApiBizApplyServiceImpl implements ApiBizApplyService {

    @Autowired
    private ProductAmountService productAmountService;
    @Autowired
    private ApiKeyAmountService apiKeyAmountService;
    @Autowired
    private ChannelUserService channelUserService;
    @Autowired
    private ApiPlanHttpHandler apiPlanHttpHandler;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductPlanService productPlanService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private UserProtocolService userProtocolService;
    @Autowired
    private ProductProtocolService productProtocolService;
    @Autowired
    private ProductPlanTypeService productPlanTypeService;
    @Autowired
    private ApiUserRegister apiUserRegister;

    @Override
    public ApiReceiveApply apply(ApiUserRequest apiUserRequest, ApiParameterBO apiParameterBO, ProductApplyFlowPO productApplyFlowPO) throws RollBackException {
        //  获取主体计划
        ProductPlanPO productPlanPO = productPlanService.get(productApplyFlowPO.getLoanProductPlanId());
        //  获取主体信息
        ProductPO productPO = productService.get(productApplyFlowPO.getLoanProductId());

        //  获取用户流程
        ChannelUserRegisterPO userRegisterPO = channelUserService.get(ChannelUserQO.createPhone(apiUserRequest.getPhone()));
        if (ValidParam.isNull(userRegisterPO)) {
            //  注册用户
            ApiUserRegisterBO apiUserRegisterBO = apiUserRegister.applyUserRegister(apiParameterBO, productApplyFlowPO);
            userRegisterPO = apiUserRegisterBO.getUserRegisterPO();
        }

        //  设置地区信息
        DistrictPO districtPO = DistrictCache.getByName(apiUserRequest.getCity());
        apiUserRequest.setAreaCode(districtPO.getCode());
        apiUserRequest.setProvinceCode(districtPO.getProvinceCode());
        apiUserRequest.setProvinceName(districtPO.getProvinceName());

        //  记录流程
        ProductApplyFlowPO insertProductApplyFlowPO = new ProductApplyFlowPO();
        insertProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        insertProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        insertProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        insertProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        insertProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        insertProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.APPLY_ERROR.getType());
        insertProductApplyFlowPO.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        insertProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        insertProductApplyFlowPO.setBizStatus("0");
        insertProductApplyFlowPO.setAreaName(apiUserRequest.getCity());
        insertProductApplyFlowPO.setAreaCode(apiUserRequest.getAreaCode());

        //  验证计划时间
        boolean hasLimitTime = apiBizRequiredService.hasLimitTime(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(hasLimitTime, new ApiMsgException(ApiEnum.API_RECEIVE_ORG_PLAN_TIME_ERROR));

        //  进件城市是否与上一个业务流程城市一致
        boolean hasConsistentCity = apiBizRequiredService.requiredApplyCity(insertProductApplyFlowPO, apiUserRequest, productApplyFlowPO.getAreaName());
        Assert.isTrueThrows(hasConsistentCity, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_CITY_ERROR));

        //  进件资质校验
        List<SelectedUserFormBO> listUserFormBO = apiParameterBO.getListUserFormBO();
        Map<String, String> userFormMap = MapUtils.newHashMap(newMap -> IteratorUtils.array(listUserFormBO, t -> newMap.put(t.getMappingName(), t.getMappingValue())));

        boolean requiredApplyForm = apiBizRequiredService.requiredApplyForm(insertProductApplyFlowPO, productPlanPO, userFormMap);
        Assert.isTrueThrows(requiredApplyForm, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_NOW_PLAN_FIELD_ERROR));

        //  验证机构余额是否足够本次扣款
        boolean requiredProductAmount = apiBizRequiredService.requiredProductAmount(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(requiredProductAmount, new ApiMsgException(ApiEnum.API_RECEIVE_ORG_AMOUNT_MAX));

        //  验证空号检测
        boolean requiredPhoneStatus = apiBizRequiredService.requiredPhoneStatus(insertProductApplyFlowPO, productPlanPO, userRegisterPO.getPhone());
        Assert.isTrueThrows(requiredPhoneStatus, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_EMPTY_PHONE));

        //  是否本地机构计划
        if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
            insertProductApplyFlowPO.setCallUrl("本地甲方CRM");
        }

        //  API接口计划
        boolean hasPlatform = productPlanTypeService.hasPlatformPlan(productPlanPO);
        boolean hasApiOrgPlan = productPlanTypeService.hasApiOrgPlan(productPO, productPlanPO);
        boolean hasApiSpecialPlan = productPlanTypeService.hasApiSpecialPlan(productPO, productPlanPO);

        if (hasPlatform || hasApiOrgPlan || hasApiSpecialPlan) {
            Long reqId = insertProductApplyFlowPO.getReqId();
            //  设置API参数数据
            apiUserRequest.setProductId(insertProductApplyFlowPO.getLoanProductId());
            apiUserRequest.setProductPlanId(insertProductApplyFlowPO.getLoanProductPlanId());
            apiUserRequest.setLoanChannelId(insertProductApplyFlowPO.getLoanChannelId());
            apiUserRequest.setReqId(reqId.toString());

            //  发送进件
            ApiHttpMessage httpMessage = apiPlanHttpHandler.sendApply(apiUserRequest, productPO, productPlanPO);
            insertProductApplyFlowPO.setCallUrl(productPO.getApiApplyUrl());
            insertProductApplyFlowPO.setSourceReqData(httpMessage.getSourceRequestBody());
            insertProductApplyFlowPO.setReqData(String.valueOf(httpMessage.getRequestBody()));
            insertProductApplyFlowPO.setRespData(httpMessage.getResponseBody());
            insertProductApplyFlowPO.setRespCode(String.valueOf(httpMessage.getRespCode()));

            //  是否返回HTTP异常
            boolean hasHttpExp = apiBizRequiredService.hasHttpExp(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (hasHttpExp) {
                throw new ApiMsgException(ApiEnum.API_RECEIVE_ORG_ERROR);
            }
            //  是否进件返回失败
            boolean hasHttpRespBizSuc = apiBizRequiredService.hasHttpRespBizSuc(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (!hasHttpRespBizSuc) {
                throw new ApiMsgException(ApiEnum.API_RECEIVE_ORG_FAIL);
            }

            //  记录下游用户协议
            if (hasPlatform) {
                ProductProtocolQO productProtocolQO = new ProductProtocolQO();
                productProtocolQO.setProductId(productApplyFlowPO.getLoanProductId());
                productProtocolQO.setHasNeedText(true);
                List<ProductProtocolPO> listProductProtocol = productProtocolService.list(productProtocolQO);

                //  添加下游协议
                for (ProductProtocolPO productProtocolPO : listProductProtocol) {
                    String productTemplate = productProtocolPO.getText();

                    //  查询平台模板
                    UserProtocolPO userProtocolPO = new UserProtocolPO();
                    userProtocolPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
                    userProtocolPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
                    userProtocolPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
                    userProtocolPO.setLoanProductProtocolId(productProtocolPO.getId());
                    userProtocolPO.setLoanUserId(userRegisterPO.getId());
                    userProtocolPO.setPhoneMd5(userRegisterPO.getPhoneMd5());
                    userProtocolPO.setUrl(H5DomainUrlUtils.createUserProtocolUrl(productApplyFlowPO.getLoanProductPlanId(), userRegisterPO.getPhoneMd5()));
                    userProtocolPO.setType(UserProtocolEnum.PRODUCT.getType());
                    userProtocolPO.setCreateTime(DateUtils.currentTime());
                    //  填充模板
                    RespPlatformPhoneMd5DataExchange apiPlatFormDataExchange = RespPlatformPhoneMd5DataExchange.parseByJson(productApplyFlowPO.getRespData());
                    String appendedTemplate = userProtocolService.appendTemplate(userRegisterPO, productTemplate, apiPlatFormDataExchange);
                    userProtocolPO.setText(appendedTemplate);
                    userProtocolService.insert(userProtocolPO);
                }
            }
        }

        //  用户数据关联机构并记录流程数据
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.USER_ACCEPT.getType());
        insertProductApplyFlowPO.setBizStatus("1");

        //  分发的是本地CRM已经有件时则返回进件失败，只要一次件
        if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
            try {
                apiUserRegister.uniqueBindProductUser(insertProductApplyFlowPO, userRegisterPO.getId());
            } catch (Exception e) {
                throw new ApiMsgException(ApiEnum.API_USER_INFO_EXIST.format("进件"));
            }
        } else {
            //  如果分发的是平台/API机构计划则忽略限制
            apiUserRegister.multiBindProductUser(insertProductApplyFlowPO, userRegisterPO.getId());
        }

        //  主体-单次计费业务
        RespPlatformPhoneMd5DataExchange apiPlatFormDataExchange = null;
        //  平台计划解析撞库成功时的单价
        if (hasPlatform) {
            apiPlatFormDataExchange = RespPlatformPhoneMd5DataExchange.parseByJson(productApplyFlowPO.getRespData());
        }
        BigDecimal originalPrice = hasPlatform ? apiPlatFormDataExchange.getPrice() : null;

        //  下游主体计费
        ProductAmountBO productAmountBO = new ProductAmountBO();
        productAmountBO.setProductId(productPlanPO.getLoanProductId());
        productAmountBO.setProductPlanId(productPlanPO.getId());
        productAmountBO.setUserId(userRegisterPO.getId());
        productAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
        productAmountBO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        productAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
        productAmountBO.setOriginalPrice(originalPrice);
        productAmountBO.setHasPlatform(hasPlatform);
        productAmountBO.setHasLocalExist(apiParameterBO.getHasLocalExist());
        BigDecimal planPrice = productAmountService.deduct(productAmountBO);

        //  发送短信-非平台才发送短信及非唤醒
        if (!hasPlatform && !apiParameterBO.getHasLocalExist()) {
            smsService.sendCustomerNotice(userRegisterPO.getPhone(), productPlanPO.getDisplayName());
        }

        //  返回进件消息对象
        ApiReceiveApply apiReceiveApply = new ApiReceiveApply();
        apiReceiveApply.setApiClientId(productApplyFlowPO.getApiClientId());
        //  平台计划赋值
        if (hasPlatform) {
            apiReceiveApply.setOrgName(apiPlatFormDataExchange.getDisplayName());
            apiReceiveApply.setDisplayName(apiPlatFormDataExchange.getProductName());

            //  分润模式赋值
            BigDecimal share = productPlanPO.getShare();
            if (!Eq.str(share.toString(), "0.00")) {
                BigDecimal cps = apiPlatFormDataExchange.calculateSharePrice(share);
                apiReceiveApply.setPrice(cps);
            } else {
                apiReceiveApply.setPrice(productPlanPO.getPrice());
            }
        } else {
            apiReceiveApply.setOrgName(productPO.getName());
            apiReceiveApply.setDisplayName(productPlanPO.getDisplayName());
            apiReceiveApply.setPrice(productPlanPO.getPrice());
        }

        //  API渠道-扣款业务-多推模式不记录渠道费用
        if (!apiParameterBO.getHasMultiPush()) {
            ApiKeyAmountBO apiKeyAmountBO = new ApiKeyAmountBO();
            apiKeyAmountBO.setProductId(productPlanPO.getLoanProductId());
            apiKeyAmountBO.setProductPlanId(productPlanPO.getId());
            apiKeyAmountBO.setUserId(userRegisterPO.getId());
            apiKeyAmountBO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
            apiKeyAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
            apiKeyAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
            apiKeyAmountBO.setPlanPrice(planPrice);
            apiKeyAmountBO.setHasPlatform(hasPlatform);
            apiKeyAmountBO.setHasLocalExist(apiParameterBO.getHasLocalExist());
            apiKeyAmountService.deduct(apiKeyAmountBO);
        }

        apiReceiveApply.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        apiReceiveApply.setPhone(userRegisterPO.getPhone());
        apiReceiveApply.setCallUrl(H5DomainUrlUtils.createH5CallUrl(productApplyFlowPO.getPhoneMd5(), productApplyFlowPO.getApiClientId()));
        apiReceiveApply.setProductApplyFlowPO(insertProductApplyFlowPO);
        apiReceiveApply.setBizMsg(ApiEnum.API_SIGN_SUC.getMsg());
        apiReceiveApply.setBizCode(ApiEnum.API_SIGN_SUC.getCode());
        return apiReceiveApply;
    }

    @Override
    public ApiReceiveApply applyPhoneMask(ApiUserRequest apiUserRequest, ApiParameterBO apiParameterBO, ProductApplyFlowPO productApplyFlowPO) throws RollBackException {
        //  获取主体计划
        ProductPlanPO productPlanPO = productPlanService.get(productApplyFlowPO.getLoanProductPlanId());
        //  获取主体信息
        ProductPO productPO = productService.get(productApplyFlowPO.getLoanProductId());

        //  获取用户流程
        ChannelUserRegisterPO userRegisterPO = channelUserService.get(ChannelUserQO.createPhone(apiUserRequest.getPhone()));
        if (ValidParam.isNull(userRegisterPO)) {
            //  注册用户
            ApiUserRegisterBO apiUserRegisterBO = apiUserRegister.applyUserRegister(apiParameterBO, productApplyFlowPO);
            userRegisterPO = apiUserRegisterBO.getUserRegisterPO();
        }

        //  设置地区信息
        DistrictPO districtPO = DistrictCache.getByName(apiUserRequest.getCity());
        apiUserRequest.setAreaCode(districtPO.getCode());
        apiUserRequest.setProvinceCode(districtPO.getProvinceCode());
        apiUserRequest.setProvinceName(districtPO.getProvinceName());

        //  记录流程
        ProductApplyFlowPO insertProductApplyFlowPO = new ProductApplyFlowPO();
        insertProductApplyFlowPO.setApiClientId(productApplyFlowPO.getApiClientId());
        insertProductApplyFlowPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        insertProductApplyFlowPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
        insertProductApplyFlowPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
        insertProductApplyFlowPO.setReqId(productApplyFlowPO.getReqId());
        insertProductApplyFlowPO.setSrcType(ProductApplyFlowSrcTypeEnum.API.getType());
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.APPLY_ERROR.getType());
        insertProductApplyFlowPO.setPhoneMd5(userRegisterPO.getPhoneMd5());
        insertProductApplyFlowPO.setCreateTime(DateUtils.currentTime());
        insertProductApplyFlowPO.setBizStatus("0");
        insertProductApplyFlowPO.setAreaName(apiUserRequest.getCity());
        insertProductApplyFlowPO.setAreaCode(apiUserRequest.getAreaCode());

        //  验证计划时间
        boolean hasLimitTime = apiBizRequiredService.hasLimitTime(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(hasLimitTime, new ApiMsgException(ApiEnum.API_RECEIVE_ORG_PLAN_TIME_ERROR));

        //  进件城市是否与上一个业务流程城市一致
        boolean hasConsistentCity = apiBizRequiredService.requiredApplyCity(insertProductApplyFlowPO, apiUserRequest, productApplyFlowPO.getAreaName());
        Assert.isTrueThrows(hasConsistentCity, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_CITY_ERROR));

        //  进件资质校验
        List<SelectedUserFormBO> listUserFormBO = apiParameterBO.getListUserFormBO();
        Map<String, String> userFormMap = MapUtils.newHashMap(newMap -> IteratorUtils.array(listUserFormBO, t -> newMap.put(t.getMappingName(), t.getMappingValue())));

        boolean requiredApplyForm = apiBizRequiredService.requiredApplyForm(insertProductApplyFlowPO, productPlanPO, userFormMap);
        Assert.isTrueThrows(requiredApplyForm, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_NOW_PLAN_FIELD_ERROR));

        //  验证机构余额是否足够本次扣款
        boolean requiredProductAmount = apiBizRequiredService.requiredProductAmount(insertProductApplyFlowPO, productPlanPO, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
        Assert.isTrueThrows(requiredProductAmount, new ApiMsgException(ApiEnum.API_RECEIVE_ORG_AMOUNT_MAX));

        //  验证空号检测
        boolean requiredPhoneStatus = apiBizRequiredService.requiredPhoneStatus(insertProductApplyFlowPO, productPlanPO, userRegisterPO.getPhone());
        Assert.isTrueThrows(requiredPhoneStatus, new ApiMsgException(ApiEnum.API_RECEIVE_APPLY_EMPTY_PHONE));

        //  是否本地机构计划
        if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
            insertProductApplyFlowPO.setCallUrl("本地甲方CRM");
        }

        //  API接口计划
        boolean hasPlatform = productPlanTypeService.hasPlatformPlan(productPlanPO);
        boolean hasApiOrgPlan = productPlanTypeService.hasApiOrgPlan(productPO, productPlanPO);
        boolean hasApiSpecialPlan = productPlanTypeService.hasApiSpecialPlan(productPO, productPlanPO);

        if (hasPlatform || hasApiOrgPlan || hasApiSpecialPlan) {
            Long reqId = insertProductApplyFlowPO.getReqId();
            //  设置API参数数据
            apiUserRequest.setProductId(insertProductApplyFlowPO.getLoanProductId());
            apiUserRequest.setProductPlanId(insertProductApplyFlowPO.getLoanProductPlanId());
            apiUserRequest.setLoanChannelId(insertProductApplyFlowPO.getLoanChannelId());
            apiUserRequest.setReqId(reqId.toString());

            //  发送进件
            ApiHttpMessage httpMessage = apiPlanHttpHandler.sendApply(apiUserRequest, productPO, productPlanPO);
            insertProductApplyFlowPO.setCallUrl(productPO.getApiApplyUrl());
            insertProductApplyFlowPO.setSourceReqData(httpMessage.getSourceRequestBody());
            insertProductApplyFlowPO.setReqData(String.valueOf(httpMessage.getRequestBody()));
            insertProductApplyFlowPO.setRespData(httpMessage.getResponseBody());
            insertProductApplyFlowPO.setRespCode(String.valueOf(httpMessage.getRespCode()));

            //  是否返回HTTP异常
            boolean hasHttpExp = apiBizRequiredService.hasHttpExp(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (hasHttpExp) {
                throw new ApiMsgException(ApiEnum.API_RECEIVE_ORG_ERROR);
            }
            //  是否进件返回失败
            boolean hasHttpRespBizSuc = apiBizRequiredService.hasHttpRespBizSuc(insertProductApplyFlowPO, httpMessage, true, ProductApplyFlowStatusEnum.APPLY_ERROR);
            if (!hasHttpRespBizSuc) {
                throw new ApiMsgException(ApiEnum.API_RECEIVE_ORG_FAIL);
            }

            //  记录下游用户协议
            if (hasPlatform) {
                ProductProtocolQO productProtocolQO = new ProductProtocolQO();
                productProtocolQO.setProductId(productApplyFlowPO.getLoanProductId());
                productProtocolQO.setHasNeedText(true);
                List<ProductProtocolPO> listProductProtocol = productProtocolService.list(productProtocolQO);

                //  添加下游协议
                for (ProductProtocolPO productProtocolPO : listProductProtocol) {
                    String productTemplate = productProtocolPO.getText();

                    //  查询平台模板
                    UserProtocolPO userProtocolPO = new UserProtocolPO();
                    userProtocolPO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
                    userProtocolPO.setLoanProductId(productApplyFlowPO.getLoanProductId());
                    userProtocolPO.setLoanProductPlanId(productApplyFlowPO.getLoanProductPlanId());
                    userProtocolPO.setLoanProductProtocolId(productProtocolPO.getId());
                    userProtocolPO.setLoanUserId(userRegisterPO.getId());
                    userProtocolPO.setPhoneMd5(userRegisterPO.getPhoneMd5());
                    userProtocolPO.setUrl(H5DomainUrlUtils.createUserProtocolUrl(productApplyFlowPO.getLoanProductPlanId(), userRegisterPO.getPhoneMd5()));
                    userProtocolPO.setType(UserProtocolEnum.PRODUCT.getType());
                    userProtocolPO.setCreateTime(DateUtils.currentTime());

                    //  填充模板
                    RespPlatformMultiPhoneMaskDataExchange respMultiPhoneMask = JsonUtils.toBean(productApplyFlowPO.getRespData(), RespPlatformMultiPhoneMaskDataExchange.class);
                    String applyId = apiUserRequest.getApplyId();
                    //  获取原始撞库apply对应进件apply数据
                    List<RespPlatformPhoneMaskDataExchange> listPhoneMask = respMultiPhoneMask.getListPhoneMask();
                    RespPlatformPhoneMaskDataExchange findPhoneMask = CollUtils.findOne(listPhoneMask, phoneMaskDataExchange -> phoneMaskDataExchange.getApplyId().equals(applyId));

                    String appendedTemplate = userProtocolService.appendTemplatePhoneMask(userRegisterPO, productTemplate, findPhoneMask);
                    userProtocolPO.setText(appendedTemplate);
                    userProtocolService.insert(userProtocolPO);
                }
            }
        }

        //  用户数据关联机构并记录流程数据
        insertProductApplyFlowPO.setStatus(ProductApplyFlowStatusEnum.USER_ACCEPT.getType());
        insertProductApplyFlowPO.setBizStatus("1");

        //  分发的是本地CRM已经有件时则返回进件失败，只要一次件
        if (productPlanTypeService.hasLocalOrgPlan(productPO, productPlanPO)) {
            try {
                apiUserRegister.uniqueBindProductUser(insertProductApplyFlowPO, userRegisterPO.getId());
            } catch (Exception e) {
                throw new ApiMsgException(ApiEnum.API_USER_INFO_EXIST.format("进件"));
            }
        } else {
            //  如果分发的是平台/API机构计划则忽略限制
            apiUserRegister.multiBindProductUser(insertProductApplyFlowPO, userRegisterPO.getId());
        }

        //  主体-单次计费业务
        RespPlatformPhoneMaskDataExchange apiPlatFormDataExchange = null;
        //  平台计划解析撞库成功时的单价
        if (hasPlatform) {
            String applyId = apiUserRequest.getApplyId();
            RespPlatformMultiPhoneMaskDataExchange respMultiPhoneMask = JsonUtils.toBean(productApplyFlowPO.getRespData(), RespPlatformMultiPhoneMaskDataExchange.class);
            List<RespPlatformPhoneMaskDataExchange> listPhoneMask = respMultiPhoneMask.getListPhoneMask();
            apiPlatFormDataExchange = CollUtils.findOne(listPhoneMask, phoneMaskDataExchange -> phoneMaskDataExchange.getApplyId().equals(applyId));
        }
        BigDecimal originalPrice = hasPlatform ? apiPlatFormDataExchange.getPrice() : null;

        //  下游主体计费
        ProductAmountBO productAmountBO = new ProductAmountBO();
        productAmountBO.setProductId(productPlanPO.getLoanProductId());
        productAmountBO.setProductPlanId(productPlanPO.getId());
        productAmountBO.setUserId(userRegisterPO.getId());
        productAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
        productAmountBO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
        productAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
        productAmountBO.setOriginalPrice(originalPrice);
        productAmountBO.setHasPlatform(hasPlatform);
        productAmountBO.setHasLocalExist(apiParameterBO.getHasLocalExist());
        BigDecimal planPrice = productAmountService.deduct(productAmountBO);

        //  发送短信-非平台才发送短信及非唤醒
        if (!hasPlatform && !apiParameterBO.getHasLocalExist()) {
            smsService.sendCustomerNotice(userRegisterPO.getPhone(), productPlanPO.getDisplayName());
        }

        //  返回进件消息对象
        ApiReceiveApply apiReceiveApply = new ApiReceiveApply();
        apiReceiveApply.setApiClientId(productApplyFlowPO.getApiClientId());
        //  平台计划赋值
        if (hasPlatform) {
            apiReceiveApply.setOrgName(apiPlatFormDataExchange.getDisplayName());
            apiReceiveApply.setDisplayName(apiPlatFormDataExchange.getProductName());

            //  分润模式赋值
            BigDecimal share = productPlanPO.getShare();
            if (!Eq.str(share.toString(), "0.00")) {
                BigDecimal cps = apiPlatFormDataExchange.calculateSharePrice(share);
                apiReceiveApply.setPrice(cps);
            } else {
                apiReceiveApply.setPrice(productPlanPO.getPrice());
            }
        } else {
            apiReceiveApply.setOrgName(productPO.getName());
            apiReceiveApply.setDisplayName(productPlanPO.getDisplayName());
            apiReceiveApply.setPrice(productPlanPO.getPrice());
        }

        //  API渠道-扣款业务-多推模式不记录渠道费用
        if (!apiParameterBO.getHasMultiPush()) {
            ApiKeyAmountBO apiKeyAmountBO = new ApiKeyAmountBO();
            apiKeyAmountBO.setProductId(productPlanPO.getLoanProductId());
            apiKeyAmountBO.setProductPlanId(productPlanPO.getId());
            apiKeyAmountBO.setUserId(userRegisterPO.getId());
            apiKeyAmountBO.setLoanChannelId(productApplyFlowPO.getLoanChannelId());
            apiKeyAmountBO.setApiClientId(productApplyFlowPO.getApiClientId());
            apiKeyAmountBO.setPhoneMd5(userRegisterPO.getPhoneMd5());
            apiKeyAmountBO.setPlanPrice(planPrice);
            apiKeyAmountBO.setHasPlatform(hasPlatform);
            apiKeyAmountBO.setHasLocalExist(apiParameterBO.getHasLocalExist());
            apiKeyAmountService.deduct(apiKeyAmountBO);
        }

        apiReceiveApply.setPhoneMd5(productApplyFlowPO.getPhoneMd5());
        apiReceiveApply.setPhone(userRegisterPO.getPhone());
        apiReceiveApply.setCallUrl(H5DomainUrlUtils.createH5CallUrl(productApplyFlowPO.getPhoneMd5(), productApplyFlowPO.getApiClientId()));
        apiReceiveApply.setProductApplyFlowPO(insertProductApplyFlowPO);
        apiReceiveApply.setBizMsg(ApiEnum.API_SIGN_SUC.getMsg());
        apiReceiveApply.setBizCode(ApiEnum.API_SIGN_SUC.getCode());
        return apiReceiveApply;
    }
}
